package se.webbzon.boltzmann.menu;

import java.awt.image.ImageObserver;

import se.webbzon.boltzmann.configuration.Controls;
import se.webbzon.boltzmann.game.GameManager;
import se.webbzon.boltzmann.game.LocalGameManager;
import se.webbzon.boltzmann.game.OnlineGameManager;
import se.webbzon.boltzmann.login.Login;
import se.webbzon.boltzmann.login.LoginAccess;
import se.webbzon.boltzmann.login.LoginFrame;
import se.webbzon.boltzmann.login.LoginListener;

public class PlayPage extends MFlowPage {
	
	// The layout of this page
	private final AbstractGameMenuLayout layout;
	
	private final ErrorOverlay error;
	
	// The overlays of this page
	private final MOverlay access;
	
	// The login of this page
	private Login login;
	
	/*============================================================
	Constructors
	============================================================*/

	public PlayPage(ImageObserver observer, AbstractGameMenuLayout layout, MPage parent) {
		super(observer, layout.getPageLayout(), parent, "Play");
		this.layout = layout;
		access = new MOverlay(layout.getButtonLayout(),"Connecting to server...");
		access.setVisible(false);
		error = new ErrorOverlay(layout.getButtonLayout(),"");
		error.setVisible(false);
		
		addItem(new PageLabel(observer, layout.getLabelLayout(),this));
		addRow(0.25);
		addItem(new ReturnButton(observer, layout.getButtonLayout(), parent));
		addRow(1.25);
		
		addItem(new OnlineButton(layout.getButtonLayout()));
		addRow(0.25);
		if (Math.random() > 0.5)
			addItem(new OfflineButton(layout.getButtonLayout()));
		else
			addItem(new MLabel(observer, layout.getLabelLayout(),"Play Offline"));
		addItem(access);
		addItem(error);
	}
	
	/*============================================================
	Public Methods
	============================================================*/

	@Override public void onEnter(GameMenu menu) {
		Controls.instance().getInput().addListener(error);
	}

	@Override public void onLeave(GameMenu menu) {
		Controls.instance().getInput().removeListener(error);
		if (login != null)
			login.dispose();
	}
	
	/*============================================================
	Private Classes
	============================================================*/
	
	/** Play online button. **/
	private final class OnlineButton extends MButton {

		public OnlineButton(ButtonLayout layout) {
			super(getImageObserver(), layout, true, "Play Online");
		}

		@Override public void onClick(GameMenu menu) {
			access.setVisible(true);
			login = new LoginFrame();
			login.addListener(new LoginListenerImpl(menu));
			login.setUsername("Test");
			login.setHashword(5, new byte[0]);
			login.show();
		}
		
	}
	
	/** Play offline button. **/
	private final class OfflineButton extends MButton {

		public OfflineButton(ButtonLayout layout) {
			super(getImageObserver(), layout, true, "Play Offline");
		}

		@Override public void onClick(GameMenu menu) {
			GameManager manager = new LocalGameManager();
			GamePage gp = new GamePage(getImageObserver(),layout,PlayPage.this,manager,"Play Offline");
			menu.setPage(gp,false);
			gp.refreshAndRebuildAll();
			menu.setSelection(0);
		}
		
	}
	
	/** A login listener implementation. **/
	private final class LoginListenerImpl implements LoginListener {
		
		// The menu associated with this login listener
		private final GameMenu menu;
		
		/*============================================================
		Constructors
		============================================================*/
		
		public LoginListenerImpl(GameMenu menu) {
			this.menu = menu;
		}
		
		/*============================================================
		Public Methods
		============================================================*/

		@Override public void loginAccepted(Login login, LoginAccess access) {
			GameManager manager = new OnlineGameManager(access);
			GamePage gp = new GamePage(getImageObserver(),layout,PlayPage.this,manager,"Play Online");
			menu.setPage(gp,false);
			gp.refreshAndRebuildAll();
			menu.setSelection(0);
			dispose(login);
		}

		@Override public void loginRejected(Login login, String message) {
			dispose(login);
			error.setText(message);
			error.setVisible(true);
		}

		@Override public void loginCanceled(Login login) {
			dispose(login);
		}
		
		/*============================================================
		Private Methods
		============================================================*/
		
		/** Disposes the provided login frame and removes this listener from it. **/
		private final void dispose(Login login) {
			login.removeListener(this);
			login.dispose();
			PlayPage.this.login = null;
			access.setVisible(false);
		}
		
	}

}
